/*
 * GeoVISTA Center (Penn State, Dept. of Geography)
 * Copyright (c), 2003-2011,  Jin Chen and Alan M. MacEachren, GeoVISTA Center, Penn State University
 * All Rights Researved.
 *
 * This library is developed and distributed for free usage,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * You can redistribute and/or modify it under the terms of the
 * Simplified BSD License
 *
 *
 *
 *
 *
 *
 *
 * The scrollpane will automatically scroll to show more view if you drag the mouse approaching the edge of the scrollpane
 * @author: jin Chen
 * @date: Oct 15, 2003$
 * @version: 1.0
 */
package edu.psu.geovista.app.pcp.toolkits.scrollpane;

import javax.swing.*;
import javax.swing.event.MouseInputAdapter;
import javax.swing.plaf.basic.BasicScrollPaneUI;
import java.awt.*;
import java.awt.event.MouseEvent;

public class AutoScrollablePane extends JScrollPane{
    public static final boolean DEBUG = false;
    int offset=20;
    int defaultScrollRate=15;
    public AutoScrollablePane() {
    }

    public AutoScrollablePane(Component view) {
        super(view);
        view.addMouseMotionListener(new AutoScrollControl());
    }
    /**
     * scroll horizontally
     * @param horizontal      true, scroll horizontally. false, vertically
     * @param moveRate   how fast it is move. Default is 1, 10 is faster.
     *                   >0 move right, <0 move left
     */
    public void scroll(boolean horizontal,int moveRate) {
        BasicScrollPaneUI  ui=(BasicScrollPaneUI) this.getUI() ;

        JScrollBar hbar=null;
        if (horizontal) {
            hbar = this.getHorizontalScrollBar();
        } else {
            hbar = this.getVerticalScrollBar() ;
        }
        int cur=hbar.getValue();

        //System.out.println("cur:"+cur);

        int move=hbar.getUnitIncrement() *moveRate;
        //System.out.println("move:"+move);
        hbar.setValue(cur+move);

    }


    /**
     *  To understand the values
     * @param x
     */
    private void test(int x){
        JViewport vp=this.getViewport() ;
        Point p=vp.getViewPosition();
        System.out.println("view position:"+p.x+","+p.y);

        Dimension vptSize=vp.getSize() ;
        System.out.println("Viewport getSize:"+vptSize.width +","+vptSize.height );


        Dimension size=vp.getViewSize() ;
        System.out.println("Viewport getViewSize:"+size.width +","+size.height );



    }
    /**
     * Given mouse position, determine whether to scroll and in what direction to scroll.
     * The mouse position is the value in view's(client component) coordinate
     * @param x     current x
     * @param y     current y
     * @param lx    x value of last mouse position
     * @param ly    y value of last mouse position
     */
    private void tryToScroll(int lx, int ly,int x, int y) {
        boolean moveRight =true;//horizontal direction
        boolean moveDown=true;//vertical direction
        if (x<lx){
            moveRight=false;
        }
        if(y<ly){
            moveDown=false;
        }

        JViewport vp=this.getViewport() ;
        Point p=vp.getViewPosition();// 
        //dp{
        if (DEBUG){
            System.out.println("view position:"+p.x+","+p.y);
        }//dp}
        //
        Dimension vptSize=vp.getSize() ;// 
        Dimension scrollSize=this.getSize();
        //dp{
        if (DEBUG){
            System.out.println("scrollSize:"+scrollSize.width +","+scrollSize.height );
        }//dp}
        //
        //dp{
        if (DEBUG){
            System.out.println("Viewport getSize:"+vptSize.width +","+vptSize.height );
        }//dp}

        Dimension size=vp.getViewSize() ;
        //dp{
        if (DEBUG){
           System.out.println("Viewport getViewSize:"+size.width +","+size.height );

        }//dp}


        if(p.x+vptSize.width-x<=offset&&moveRight){
           this.scroll(true,this.defaultScrollRate );
        }
        else if(x-p.x <=offset&&!moveRight){
            this.scroll(true,-this.defaultScrollRate );
        }

        if(p.y+vptSize.height -y<=offset&&moveDown){
           this.scroll(false,this.defaultScrollRate );
        }
        else if(y-p.y <=offset&&!moveDown){
            this.scroll(false,-this.defaultScrollRate );
        }

    }
    class AutoScrollControl extends MouseInputAdapter{
        Point last=new Point();
        public void mouseDragged(MouseEvent e){
              int x=e.getX() ;
              int y=e.getY() ;
             // System.out.println(" cur point ("+x+","+y+")");
              //System.out.println(" last point ("+last.x+","+last.y+")");
              tryToScroll(last.x ,last.y, x,y);
              last.setLocation(x,y);
              //System.out.println("x:"+x+" y:"+y);
            //test(x);


        }
       public void mouseClicked(MouseEvent e) {
           int x=e.getX() ;
              int y=e.getY() ;
          // System.out.println("x:"+x+" y:"+y);
       }
    }
    
}

